Überblick

Begleitendes Beispiel (Ilg / Baumeister 2019).

Datenherkunft

Schweizerische Eidgenossenschaft - Bundesamt für Statistik.
Abgerufen aus STAT-TAB am 24.8.2019:
https://www.pxweb.bfs.admin.ch/pxweb/de/px-x-1103020200_120/-/px-x-1103020200_120.px

Datenaufbereitung

Die Daten wurden aus STAT-TAB als csv-Datei exportiert.

Sofort fällt der Peak im Juni 2012 bei Inverkehrssetzungen auf - verursacht durch eine Änderung der CO2-Emissionsvorschriften ab Juli 2012 (https://www.bfs.admin.ch/bfs/de/home/dienstleistungen/fuer-medienschaffende/medienmitteilungen.assetdetail.36344.html).

Für den Zweck der Analyse - eine Prognose der Entwicklung des Automobilmarktes für ein Jahr, ist dieser Ausreißer eher störend. Sinnvoller ist es auf Daten ab 2013 zurückzugreifen. Ein erster Blick auf die Daten mit summary zeigt, dass sich die Inverkehrssetzungen im Intervall von 19.129 bis 35.008 bewegen, im Durchschnitt sind es 26.064 Inverkehrssetzungen. Es werden keine fehlenden Werte angezeigt.

     Datum                 IVS       
 Min.   :2013-01-31   Min.   :19129  
 1st Qu.:2014-07-23   1st Qu.:23105  
 Median :2016-01-15   Median :26184  
 Mean   :2016-01-14   Mean   :26064  
 3rd Qu.:2017-07-07   3rd Qu.:28502  
 Max.   :2018-12-31   Max.   :35008  

In der folgenden Abbildung sind die Daten aus dem Berichtsjahr 2018 blau gekennzeichnet, das sie in der Folge nicht zur Schätzung sondern zur Validierung des Modells herangezogen werden, um dessen Prognosefähigkeit beurteilen zu können. Konnte man beim Analysezeitraum 2005 - 2018 noch einen positiven lineare Trend bei Inverkehrssetzungen vermuten, so ist dies in der verkürzten Analyseperiode nicht erkennbar. Die Werte schwanken zudem erheblich, wobei die meisten (90 %) der Werte zwischen 21.700 und 31.400 Inverkehrssetzungen liegen.

Modellierung

Lineares Grundmodell

Zahlreiche Modelle werden in der Zeitreihenanalyse verwendet (vgl. einführend Backhaus et al. (2018), S. 126 ff). Beim linearen Modell erfolgt in der Grundform additive Zerlegung \(Y = A + K + S + u\) mit \(Y\) als zu erklärender Variable, \(A\) als Trendkomponente, \(K\) als Konjunkturkomponente (lange zyklische Komponente), \(S\) als Saisonkomponente und \(u\) als Störgröße oder zufällige Komponente. Im einfachsten Fall ohne Saison- und Konjunkturkomplenten reduziert sich das Modell auf \(Y = A + u\). Mit der Spezifikation der Trendkomponente \(A\) entsteht das lineare Trendmodell: \[Y = \alpha + \beta \cdot t + u\]

Auch zahlreiche nichtlineare Modelle können über geeignete Transformationen im linearem Kontext analysiert werden. Zu nennen sind bspw. das Quadradwurzelmodell \(Y = \alpha + \beta \sqrt t + u\) oder das logarithmische Modell \(Y = \alpha + \beta \cdot \ln (t) + u\) , die beide Sättigungseffekte abbilden können. Für einen Überblick über weitere Modelle und geeignete Linearisierungen vgl. Backhaus et al. (2018), S 148 ff.


Call:
lm(formula = IVS ~ Datum, data = ivs_simple)

Residuals:
    Min      1Q  Median      3Q     Max 
-6917.4 -2967.7   110.1  2465.7  8925.7 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)  
(Intercept) 2.520e+04  1.160e+04   2.172   0.0332 *
Datum       5.133e-02  6.894e-01   0.074   0.9409  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3701 on 70 degrees of freedom
Multiple R-squared:  7.918e-05, Adjusted R-squared:  -0.01421 
F-statistic: 0.005543 on 1 and 70 DF,  p-value: 0.9409

Das Bestimmheitsmaß \(R^2\) ist praktisch 0, das Modell trägt nicht zur Erklärung der Streuung der Zeitreihe bei. Sowohl das Modell insgesamt (F-Statistik) als auch die Parameterschätzung für den Regressor \(Datum\) sind nicht siginifikant.

Berücksichtigung saisonaler Schwankungen

Das lineare Trendmodell liefert keinen Erklärungsbeitrag. Werden die Datenpunkte als Liniendiagramm dargestellt, wird eine zyklische Schwankung deutlich. Für die Modellbildung werden nur die Daten von 2013 bis 2017 verwendet, 2018 wird für die Beurteilung der Modellperformance zurückgehalten.

Modelliert man die monatlichen Schwankungen, erhöht sich der Erklärungsgehalt des Modells deutlich. Dazu werden die Monate als zweistellige Zeichenketten modelliert (“01” bis “12”). R erzeugt daraus automatisch 11 Dummyvariablen zur Abbildung der Monate im Modell.


Call:
lm(formula = IVS ~ Datum + Monat, data = ivs_simple_train)

Residuals:
    Min      1Q  Median      3Q     Max 
-2676.5 -1014.5   170.3   724.4  3164.6 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 1.120e+04  6.427e+03   1.742  0.08801 .  
Datum       5.702e-01  3.880e-01   1.469  0.14839    
Monat02     2.311e+03  9.821e+02   2.353  0.02284 *  
Monat03     9.143e+03  9.823e+02   9.308 3.08e-12 ***
Monat04     7.511e+03  9.827e+02   7.644 8.71e-10 ***
Monat05     6.552e+03  9.832e+02   6.664 2.64e-08 ***
Monat06     1.018e+04  9.838e+02  10.345 1.06e-13 ***
Monat07     6.321e+03  9.846e+02   6.420 6.22e-08 ***
Monat08     1.228e+03  9.855e+02   1.246  0.21899    
Monat09     3.193e+03  9.866e+02   3.236  0.00222 ** 
Monat10     4.528e+03  9.878e+02   4.584 3.38e-05 ***
Monat11     4.778e+03  9.891e+02   4.831 1.49e-05 ***
Monat12     1.123e+04  9.906e+02  11.337 4.79e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1553 on 47 degrees of freedom
Multiple R-squared:  0.862, Adjusted R-squared:  0.8267 
F-statistic: 24.46 on 12 and 47 DF,  p-value: 3.282e-16

Der Anteil der erklärten Varianz erhöht sich nun auf über 86 Prozent. Die meisten der Saision-Dummies haben statistisch signifikante Koeffizienten, gleiches gilt für das Modell im Gesamten (vgl. F-Statistik).

Prüfung der Modellierungsvoraussetzungen

Wir prüfen die Modellierungsvoraussetzungen analog zu Backhaus et al. (2018), S. 98 ff).

  1. Nichtlinearität: die graphische Darstellung lässt - unter Berücksichtigung der Saisonkomponente einen darunter liegenden linearen Trend vermuten.

  2. Erwartungswert der Störgröße = 0: ist nicht von Bedeuutung, wirkt sich ggf. auf den Koeffizienten b0 aus.

  3. Falsche Regressorenauswahl: Multikollinearität falsch spezifizierter Regressoren verzerrt die Parmeterschätzer, bei fehlender Multikollinearität wirken sie sich zumindest wieder auf den Ordinatenabschnitt b0 aus. Mit \(Datum\) und \(Monat\) sind hier allerdings keine überflüssigen Regressoren erkennbar.

  4. Heteroskedastizität: Der Plot der Residuen gegen die erklärte Variable lässt keine für Heteroskedastizität typischen Verläufe erkennen.

Heteroskedastizität kann auch mit dem Goldfeld-Quandt-Test überprüft werden. Die Nullhypothese (Homoskedastizität) kann nicht verworfen werden.


    Goldfeld-Quandt test

data:  mod
GQ = 0.85735, df1 = 17, df2 = 17, p-value = 0.6227
alternative hypothesis: variance increases from segment 1 to 2
  1. Autokorrelation: Inbesondere bei Zeitreihen besteht die Gefahr der Verzerrung des Standardfehlers der Regressionskoeffizienten durch autokorrelierte Residuen. Im Ergebnis ergeben sich dann verzerrte Konfidenzintervalle für die Regressionskoeffizienten. Eine Visuelle Prüfung erfolgt wie bei der Heterskedastizität im Plot der Residuen gegen die geschätzen Werte. Ebenso ist die Prüfung mit Durbin-Watson-Test möglich, dessen Nullhypothese (keine Autokorrelation) nicht verworfen werden kann.

    Durbin-Watson test

data:  mod
DW = 1.9995, p-value = 0.4883
alternative hypothesis: true autocorrelation is greater than 0
  1. Multikollinearität: Schätzungen für Regressionskoeffizienten werden unzuverlässiger, wenn sich die Koeffizenten aus anderen Modellkoeffizienten errechnen lassen. Paarweise Multikollinearität ist vorhanden, wenn der Betrag der paarweisen Korrelationen nahe 1 ist. Abhängigkeiten von mehreren anderen Variablen kann durch die Toleranz oder deren Kehrwert, den Varianz-Inflation-Factor (VIF) ermittelt werden. VIF-Werte im bereich von 10 oder größer sind auf jeden Fall problematisch. Im Beispiel ist die Multikollinearität mit Datum bzw. Monat als Regressoren nicht relevant.
  1. Normalverteilung der Residuen: Bei großer Stichprobe ist eine Abweichung von der Normalverteilungsannahme nicht so tragisch. De QQ-Plot sieht allerdings nicht perfekt aus.

Erstellung von Prognosen

Das berechnete Modell erlaubt die Berechnung von Prognosewerten. Durch den Vergleich der Prognosewerte für die Testdaten mit den Ist-Werten der Testdaten (2018) können Performance-Maße berechnet werden, die den Vergleich unterschiedlicher Modelle erlauben.

Test einer alternative Modellierung als ARIMA

initial  value 7.918097 
iter   2 value 7.681026
iter   3 value 7.676791
iter   4 value 7.676511
iter   5 value 7.676506
iter   5 value 7.676506
iter   5 value 7.676506
final  value 7.676506 
converged
initial  value 7.687296 
iter   2 value 7.685275
iter   3 value 7.685063
iter   4 value 7.685061
iter   4 value 7.685061
iter   4 value 7.685061
final  value 7.685061 
converged

initial  value 7.922801 
iter   2 value 7.628224
iter   3 value 7.504898
iter   4 value 7.425491
iter   5 value 7.399672
iter   6 value 7.388361
iter   7 value 7.387792
iter   8 value 7.387773
iter   9 value 7.387767
iter  10 value 7.387766
iter  11 value 7.387766
iter  11 value 7.387766
iter  11 value 7.387766
final  value 7.387766 
converged
initial  value 7.389999 
iter   2 value 7.388560
iter   3 value 7.384479
iter   4 value 7.383381
iter   5 value 7.382753
iter   6 value 7.382553
iter   7 value 7.382544
iter   8 value 7.382541
iter   8 value 7.382541
final  value 7.382541 
converged
$fit

Call:
stats::arima(x = xdata, order = c(p, d, q), seasonal = list(order = c(P, D, 
    Q), period = S), include.mean = !no.constant, transform.pars = trans, fixed = fixed, 
    optim.control = list(trace = trc, REPORT = 1, reltol = tol))

Coefficients:
          ar1      ar2     sma1
      -0.9033  -0.7276  -0.9978
s.e.   0.0962   0.1068   0.4442

sigma^2 estimated as 1677377:  log likelihood = -413.67,  aic = 835.34

$degrees_of_freedom
[1] 44

$ttable
     Estimate     SE t.value p.value
ar1   -0.9033 0.0962 -9.3891  0.0000
ar2   -0.7276 0.1068 -6.8130  0.0000
sma1  -0.9978 0.4442 -2.2465  0.0297

$AIC
[1] 14.4024

$AICc
[1] 14.41006

$BIC
[1] 14.52999

Reduktion der Prädiktoren / V1 Saisonale Vorhersagen

Reduktion der Prädiktoren / V2 monatliche Vorhersagen mit Time Lag

Differenzierung der Antriebsart

Die Wiederholung der Analyse mit dem zusätzlichen Regressor zeigt ein völlig anderes Bild.

Die Treibstoffarten “Anderer” und “Ohne Motor” spielen in der Analyse keine besondere Rolle. Zur besseren Übersichtlichkeit werden sie ausgeschlossen.

Modelle je Treibstoffart

Modelle berechnen und plotten

Performanceberechnung

Je Treibstoffart werden für das jeweilge Modell die Modellkennzahlen ermittelt.

Fehler in Ops.data.frame(actual, predicted) : 
  list of length 13 not meaningful

Quellen

Backhaus et al. (2018): Multivariate Analysemethoden. Eine anwendungsorientierte Einführung. 15 Aufl. Berlin. Heidelberg. Springer-Verlag.

Ilg, Markus; Baumeister, Alexander (2019): Analytics im Marketing-Controlling. In: Die Digitalisierung des Controllings: Anwendungsbeispiele aus Theorie und Praxis, hrsg. von Imke Keimer und Ulrich Egle. Springer.

Ruppert, David; Matteson, David S. (2015): Statistics and Data Analysis for Financial Engineering Springer-Verlag

LS0tCnRpdGxlOiAiSW52ZXJrZWhyc3NldHp1bmdlbiBpbiBkZXIgU2Nod2VpeiIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogCi0gbmFtZSAgIDogIk1hcmt1cyBJbGciCiAgZW1haWwgOiAibWFya3VzLmlsZ0BtYXJrdXMtaWxnLmF0IgoKLS0tCgojIyMgw5xiZXJibGljawoKQmVnbGVpdGVuZGVzIEJlaXNwaWVsIChJbGcgLyBCYXVtZWlzdGVyIDIwMTkpLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgSW5pdGlhbGlzZXJ1bmcgZGVzIE5vdGVib29rcwprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQoKIyBCZW7DtnRpZ3RlIEJpYmxpb3RoZWtuIGxhZGVuCmxpYnJhcnkodGlkeXZlcnNlKSAgIyByZWFkciwgZHBseXIsIC4uLiAKbGlicmFyeShsdWJyaWRhdGUpICAjIERhdHVtIHVuZCBVaHJ6ZWl0CmxpYnJhcnkobW9kZWxyKSAgICAgIyBNb2RlbGxpZXJ1bmcKbGlicmFyeShicm9vbSkgICAgICAjIFp1c2FtbWVuZmFzc3VuZyB2b24gTW9kZWxsZXJnZWJuaXNzZW4gaW4gRGF0YWZyYW1lcwpsaWJyYXJ5KGNvcnJwbG90KSAgICAgICMgWnVzYW1tZW5mYXNzdW5nIHZvbiBNb2RlbGxlcmdlYm5pc3NlbiBpbiBEYXRhZnJhbWVzCiAKbGlicmFyeShsbXRlc3QpICAgICAjIGbDvHIgR29sZGZlbGR0L1F1YW5kdC1UZXN0CmxpYnJhcnkoY2FyKSAgICAgICAgIyBmw7xyIFZJRgoKbGlicmFyeShmb3JlY2FzdCkgICAjIGbDvHIgekIgZ2d0c2Rpc3BsYXkuCmxpYnJhcnkoYXN0c2EpICAgICAgIyBmw7xyIHNhcmltYSwgc2FyaW1hLmZvcgoKdGhlbWVfc2V0KHRoZW1lX2J3KCkpICMgQWJiaWxkdW5nZW4gaW0gRHJ1Y2sgYmVzc2VyIGxlc2JhciBhbHMgbWl0IGRlbSBEZWZhdWx0LVRoZW1lIHRoZW1lX2dyYXkoKQoKIyBCZXJlY2huZSBkZW4gbGV0enRlbiBUYWcgZGVzIE1vbmF0cwptb250aHNFbmQgPC0gZnVuY3Rpb24oSmFociwgTW9uYXQpIHsKICByZXF1aXJlKGx1YnJpZGF0ZSkKICBwYXN0ZShKYWhyLCBNb25hdCwgIjAxIiwgc2VwID0gIi0iKSAlPiUgeW1kKCkgJT4lIGNlaWxpbmdfZGF0ZSh1bml0ID0gIm1vbnRocyIpIC0gMQp9CgojIEZvcm1hdGllcmUgIjEuMjM0LDU2IiBzdGF0dCAiMSwyMzQuNTYiCmZvcm1hdFQgPC0gZnVuY3Rpb24obikgewogIGZvcm1hdChuLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKQp9CmBgYAoKIyMjIERhdGVuaGVya3VuZnQKU2Nod2VpemVyaXNjaGUgRWlkZ2Vub3NzZW5zY2hhZnQgLSBCdW5kZXNhbXQgZsO8ciBTdGF0aXN0aWsuICAKQWJnZXJ1ZmVuIGF1cyBTVEFULVRBQiBhbSAyNC44LjIwMTk6ICAKaHR0cHM6Ly93d3cucHh3ZWIuYmZzLmFkbWluLmNoL3B4d2ViL2RlL3B4LXgtMTEwMzAyMDIwMF8xMjAvLS9weC14LTExMDMwMjAyMDBfMTIwLnB4CgojIyMgRGF0ZW5hdWZiZXJlaXR1bmcKCkRpZSBEYXRlbiB3dXJkZW4gYXVzIFNUQVQtVEFCIGFscyBjc3YtRGF0ZWkgZXhwb3J0aWVydC4KCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CgojIGNzdiBhbHMgUm9oZGF0ZW4gaW1wb3J0aWVyZW4KaXZzX3JhdyA8LQogIHJlYWRfY3N2KGZpbGUgPSAiRGF0ZW4vMjAxOTA4MjQgTmV1enVsYXNzdW5nZW4gQ0guY3N2IiwKICAgICAgICAgICBza2lwID0gMiwKICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUoZW5jb2RpbmcgPSAibGF0aW4xIikpICMgV2luZG93cyBMYXRpbiAxCgojIEJlc2NocsOkbmt1bmcgYXVmIHJlbGV2YW50ZSBEYXRlbgppdnNfc2ltcGxlIDwtIGl2c19yYXcgJT4lCiAgc2VsZWN0KC0iRmFocnpldWdncnVwcGUgLyAtYXJ0IikgJT4lICMgU3BhbHRlIEZhaHJ6ZXVncnVwcGUgbMO2c2NoZW4KICBnYXRoZXIoa2V5ID0gSmFociwgdmFsdWUgPSAiSVZTIiwgLU1vbmF0KSAlPiUgIyBkaWUgSmFocmVzc3BhbHRlbiBpbiBaZWlsZW4gdW1iYXVlbgogIG11dGF0ZShEYXR1bSA9IG1vbnRoc0VuZChKYWhyLCBNb25hdCkpICU+JSAgIyBKYWhyIE1vbmF0IHVtYmF1ZW4gYXVmIGVpbmUgRGF0dW0genVtIE1vbmF0c2VuZGUKICBzZWxlY3QoRGF0dW0sIElWUykgIyBudXIgZGllIFNwYWx0ZW4gRGF0dW0gdW5kIElWUyBhdXN3w6RobGVuCgojIERhcnN0ZWxsdW5nIGRlciBtb25hdGxpY2hlbiBJbnZlcmtlaHJzc2V0enVuZ2VuIGFscyBTY2F0dGVycGxvdAppdnNfc2ltcGxlICU+JQogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKwogIHNjYWxlX3hfZGF0ZSggIyBGb3JtYXRpZXJ1bmdzYW53ZWlzdW5nZW4gZsO8ciBkaWUgeC1BY2hzZQogICAgbmFtZSA9ICIiLAogICAgZGF0ZV9sYWJlbHMgPSAiJW0vJXkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCAjIEZvcm1hdGllcnVuZ3NhbndlaXN1bmdlbiBmw7xyIGRpZSB5LUFjaHNlCiAgICBuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwKICAgIGxpbWl0cyA9IGMoMCwgNDUwMDApLAogICAgbGFiZWxzID0gZm9ybWF0VCAjIEFuemVpZ2UgZGVyIFNrYWxhIG1pdCBUYXVzZW5kZXItUHVua3QKICApICsKICBnZW9tX3BvaW50KGFlcygKICAgIHkgPSBJVlMsICMgSVZTIGF1ZiBkZXIgeS1BY2hzZQogICAgc2hhcGUgPSAoSVZTID4gNDAwMDApLCAjIGVpZ2VuZSBGb3JtIGbDvHIgV2VydGUgw7xiZXIgNDAwMDAKICAgIGNvbG9yID0gKElWUyA+IDQwMDAwKSAgIyBlaWdlbmUgRmFyYmUgZsO8ciBXZXJ0ZSDDvGJlciA0MDAwMAogICkpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgInJlZCIpKSArICMgbWFudWVsbGUgRmFyYnNrYWxhCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKSArICMgS2VpbmUgTGVnZW5kZSBmw7xyIGRpZSBGYXJiZQogIGd1aWRlcyhzaGFwZSA9ICJub25lIikgKyAjIEtlaW5lIExlZ2VuZGUgZsO8ciBkaWUgRmFyYmUKICBsYWJzKHRpdGxlID0gIm1vbmF0bGljaGUgSW52ZXJrZWhyc3NldHp1bmdlbiB2b24gUGVyc29uZW5rcmFmdHdhZ2VuIiwKICAgICAgIHN1YnRpdGxlID0gIlNjaHdlaXosIDIwMDUgLSAyMDE4IikKCmBgYAoKU29mb3J0IGbDpGxsdCBkZXIgUGVhayBpbSBKdW5pIDIwMTIgYmVpIEludmVya2VocnNzZXR6dW5nZW4gYXVmIC0gdmVydXJzYWNodCBkdXJjaCBlaW5lIMOEbmRlcnVuZyBkZXIgQ08yLUVtaXNzaW9uc3ZvcnNjaHJpZnRlbiBhYiBKdWxpIDIwMTIgKGh0dHBzOi8vd3d3LmJmcy5hZG1pbi5jaC9iZnMvZGUvaG9tZS9kaWVuc3RsZWlzdHVuZ2VuL2Z1ZXItbWVkaWVuc2NoYWZmZW5kZS9tZWRpZW5taXR0ZWlsdW5nZW4uYXNzZXRkZXRhaWwuMzYzNDQuaHRtbCkuICAKCkbDvHIgZGVuIFp3ZWNrIGRlciBBbmFseXNlIC0gZWluZSBQcm9nbm9zZSBkZXIgRW50d2lja2x1bmcgZGVzIEF1dG9tb2JpbG1hcmt0ZXMgZsO8ciBlaW4gSmFociwgaXN0IGRpZXNlciBBdXNyZWnDn2VyIGVoZXIgc3TDtnJlbmQuIFNpbm52b2xsZXIgaXN0IGVzIGF1ZiBEYXRlbiBhYiAyMDEzIHp1csO8Y2t6dWdyZWlmZW4uIEVpbiBlcnN0ZXIgQmxpY2sgYXVmIGRpZSBEYXRlbiBtaXQgYHN1bW1hcnlgIHplaWd0LCBkYXNzIHNpY2ggZGllIEludmVya2VocnNzZXR6dW5nZW4gaW0gSW50ZXJ2YWxsIHZvbiBgciBmb3JtYXRUKG1pbihpdnNfc2ltcGxlJElWUykpYCBiaXMgYHIgZm9ybWF0VChtYXgoaXZzX3NpbXBsZSRJVlMpKWAgYmV3ZWdlbiwgaW0gRHVyY2hzY2huaXR0IHNpbmQgZXMgYHIgZm9ybWF0VChyb3VuZChtZWFuKGl2c19zaW1wbGUkSVZTKSwwKSlgIEludmVya2VocnNzZXR6dW5nZW4uIEVzIHdlcmRlbiBrZWluZSBmZWhsZW5kZW4gV2VydGUgYW5nZXplaWd0LgoKYGBge3J9Cml2c19zaW1wbGUgPC0gaXZzX3NpbXBsZSAlPiUgZmlsdGVyKERhdHVtID4geW1kKCIyMDEyLTEyLTMxIikpCnN1bW1hcnkoaXZzX3NpbXBsZSkKCmBgYAoKSW4gZGVyIGZvbGdlbmRlbiBBYmJpbGR1bmcgc2luZCBkaWUgRGF0ZW4gYXVzIGRlbSBCZXJpY2h0c2phaHIgMjAxOCBibGF1IGdla2VubnplaWNobmV0LCBkYXMgc2llIGluIGRlciBGb2xnZSBuaWNodCB6dXIgU2Now6R0enVuZyBzb25kZXJuIHp1ciBWYWxpZGllcnVuZyBkZXMgTW9kZWxscyBoZXJhbmdlem9nZW4gd2VyZGVuLCB1bSBkZXNzZW4gUHJvZ25vc2Vmw6RoaWdrZWl0IGJldXJ0ZWlsZW4genUga8O2bm5lbi4gS29ubnRlIG1hbiBiZWltIEFuYWx5c2V6ZWl0cmF1bSAyMDA1IC0gMjAxOCBub2NoIGVpbmVuIHBvc2l0aXZlbiBsaW5lYXJlIFRyZW5kIGJlaSBJbnZlcmtlaHJzc2V0enVuZ2VuIHZlcm11dGVuLCBzbyBpc3QgZGllcyBpbiBkZXIgdmVya8O8cnp0ZW4gQW5hbHlzZXBlcmlvZGUgbmljaHQgZXJrZW5uYmFyLiBEaWUgV2VydGUgc2Nod2Fua2VuIHp1ZGVtIGVyaGVibGljaCwgd29iZWkgZGllIG1laXN0ZW4gKDkwICUpIGRlciBXZXJ0ZSB6d2lzY2hlbiBgciBmb3JtYXRUKHJvdW5kKHF1YW50aWxlKGl2c19zaW1wbGUkSVZTLCAwLjEwKSwgLTIpKWAgdW5kIGByIGZvcm1hdFQocm91bmQocXVhbnRpbGUoaXZzX3NpbXBsZSRJVlMsIDAuOTApLCAtMikpYCBJbnZlcmtlaHJzc2V0enVuZ2VuIGxpZWdlbi4KCmBgYHtyfQpwIDwtIGl2c19zaW1wbGUgJT4lICMgRGlhZ3JhbW1ncnVuZGRhdGVuIGZlc3RsZWdlbgogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKyAjIERhdHVtc3dlcnRlIGF1ZiBkZXIgeC1BY2hzZQogIHNjYWxlX3hfZGF0ZSgKICAgICMgRm9ybWF0aWVydW5nIGRlciB4LUFjaHNlCiAgICBuYW1lID0gIiIsCiAgICBsaW1pdHMgPSBjKHltZCgiMjAxMy0wMS0wMSIsICIyMDE4LTEyLTMxIikpLAogICAgZGF0ZV9sYWJlbHMgPSAiJW0vJXkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCAjIEZvcm1hdGllcnVuZyBkZXIgeS1BY2hzZQogICAgbmFtZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIHBybyBNb25hdCIsCiAgICBsaW1pdHMgPSBjKDAsIDQ1MDAwKSwKICAgIGxhYmVscyA9IGZvcm1hdFQpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgImJsdWUiKSkgKyAjIGVpZ2VuZSBGYXJic2thbGEKICBndWlkZXMoY29sb3IgPSAibm9uZSIpICsgIyBrZWluZSBMZWdlbmRlIGbDvHIgZGllIEZhcmJlCiAgbGFicyh0aXRsZSA9ICJtb25hdGxpY2hlIEludmVya2VocnNzZXR6dW5nZW4gdm9uIFBlcnNvbmVua3JhZnR3YWdlbiIsCiAgICAgICBzdWJ0aXRsZSA9ICJTY2h3ZWl6LCAyMDEzIC0gMjAxOCIpCgpwICsgIyBQdW5rdGUgw7xiZXIgZGFzIERpYWdyYW1tIGxlZ2VuCiAgZ2VvbV9wb2ludChhZXMoeSA9IElWUywKICAgICAgICAgICAgICAgICBjb2xvciA9ICh5ZWFyKERhdHVtKSA9PSAyMDE4KSkpCgpgYGAKCiMjIyBNb2RlbGxpZXJ1bmcKIyMjIyBMaW5lYXJlcyBHcnVuZG1vZGVsbAoKWmFobHJlaWNoZSBNb2RlbGxlIHdlcmRlbiBpbiBkZXIgWmVpdHJlaWhlbmFuYWx5c2UgdmVyd2VuZGV0ICh2Z2wuIGVpbmbDvGhyZW5kIFtCYWNraGF1cyBldCBhbC4gKDIwMTgpXShodHRwczovL3d3dy5zcHJpbmdlci5jb20vZGUvYm9vay85NzgzNjYyNTY2NTQxKSwgUy4gMTI2IGZmKS4gQmVpbSAqbGluZWFyZW4gTW9kZWxsKiBlcmZvbGd0IGluIGRlciBHcnVuZGZvcm0gYWRkaXRpdmUgWmVybGVndW5nICRZID0gQSArIEsgKyBTICsgdSQgbWl0ICRZJCBhbHMgenUgZXJrbMOkcmVuZGVyIFZhcmlhYmxlLCAkQSQgYWxzIFRyZW5ka29tcG9uZW50ZSwgJEskIGFscyBLb25qdW5rdHVya29tcG9uZW50ZSAobGFuZ2UgenlrbGlzY2hlIEtvbXBvbmVudGUpLCAkUyQgYWxzIFNhaXNvbmtvbXBvbmVudGUgdW5kICR1JCBhbHMgU3TDtnJncsO2w59lIG9kZXIgenVmw6RsbGlnZSBLb21wb25lbnRlLiBJbSBlaW5mYWNoc3RlbiBGYWxsIG9obmUgU2Fpc29uLSB1bmQgS29uanVua3R1cmtvbXBsZW50ZW4gcmVkdXppZXJ0IHNpY2ggZGFzIE1vZGVsbCBhdWYgJFkgPSBBICsgdSQuIE1pdCBkZXIgU3BlemlmaWthdGlvbiBkZXIgVHJlbmRrb21wb25lbnRlICRBJCBlbnRzdGVodCBkYXMgbGluZWFyZSBUcmVuZG1vZGVsbDogJCRZID0gXGFscGhhICsgXGJldGEgXGNkb3QgdCArIHUkJAoKQXVjaCB6YWhscmVpY2hlIG5pY2h0bGluZWFyZSBNb2RlbGxlIGvDtm5uZW4gw7xiZXIgZ2VlaWduZXRlIFRyYW5zZm9ybWF0aW9uZW4gaW0gbGluZWFyZW0gS29udGV4dCBhbmFseXNpZXJ0IHdlcmRlbi4gWnUgbmVubmVuIHNpbmQgYnNwdy4gZGFzIFF1YWRyYWR3dXJ6ZWxtb2RlbGwgJFkgPSBcYWxwaGEgKyBcYmV0YSBcc3FydCB0ICsgdSQgb2RlciBkYXMgbG9nYXJpdGhtaXNjaGUgTW9kZWxsICRZID0gXGFscGhhICsgXGJldGEgXGNkb3QgXGxuICh0KSArIHUkICwgZGllIGJlaWRlIFPDpHR0aWd1bmdzZWZmZWt0ZSBhYmJpbGRlbiBrw7ZubmVuLiBGw7xyIGVpbmVuIMOcYmVyYmxpY2sgw7xiZXIgd2VpdGVyZSBNb2RlbGxlIHVuZCBnZWVpZ25ldGUgTGluZWFyaXNpZXJ1bmdlbiB2Z2wuIFtCYWNraGF1cyBldCBhbC4gKDIwMTgpXShodHRwczovL3d3dy5zcHJpbmdlci5jb20vZGUvYm9vay85NzgzNjYyNTY2NTQxKSwgUyAxNDggZmYuCgoKYGBge3J9CiMgTGluZWFyZSBSZ3Jlc3Npb24gbWl0IGRlciBGdW5rdGlvbiBsbSwgRGF0dW0gYWxzIFJlZ3Jlc3NvciwgSVZTIGFscyBSZWdyZXNzYW5kCm1vZCA8LSBsbShmb3JtdWxhID0gSVZTIH4gRGF0dW0sIGRhdGEgPSBpdnNfc2ltcGxlKQoKIyBBdWZiZXJlaXR1bmcgZGVyIE1vZGVsbGVyZ2Vibmlzc2UgaW4gRGF0YWZyYW1lcyBtaXQgRnVua3Rpb25lbiBhdXMgZGVtIGJyb29tLXBhY2thZ2UuCnRpZHlfbW9kIDwtIHRpZHkobW9kKQpnbGFuY2VfbW9kIDwtIGdsYW5jZShtb2QpCmF1Z21lbnRfbW9kIDwtIGF1Z21lbnQobW9kKQpzdW1tYXJ5KG1vZCkKYGBgCkRhcyBCZXN0aW1taGVpdHNtYcOfICRSXjIkIGlzdCBwcmFrdGlzY2ggMCwgZGFzIE1vZGVsbCB0csOkZ3QgbmljaHQgenVyIEVya2zDpHJ1bmcgZGVyIFN0cmV1dW5nIGRlciBaZWl0cmVpaGUgYmVpLiBTb3dvaGwgZGFzIE1vZGVsbCBpbnNnZXNhbXQgKEYtU3RhdGlzdGlrKSBhbHMgYXVjaCBkaWUgUGFyYW1ldGVyc2Now6R0enVuZyBmw7xyIGRlbiBSZWdyZXNzb3IgJERhdHVtJCBzaW5kIG5pY2h0IHNpZ2luaWZpa2FudC4KCiMjIyMgQmVyw7xja3NpY2h0aWd1bmcgc2Fpc29uYWxlciBTY2h3YW5rdW5nZW4KCkRhcyBsaW5lYXJlIFRyZW5kbW9kZWxsIGxpZWZlcnQga2VpbmVuIEVya2zDpHJ1bmdzYmVpdHJhZy4gV2VyZGVuIGRpZSBEYXRlbnB1bmt0ZSBhbHMgTGluaWVuZGlhZ3JhbW0gZGFyZ2VzdGVsbHQsIHdpcmQgZWluZSB6eWtsaXNjaGUgU2Nod2Fua3VuZyBkZXV0bGljaC4gRsO8ciBkaWUgTW9kZWxsYmlsZHVuZyB3ZXJkZW4gbnVyIGRpZSBEYXRlbiB2b24gMjAxMyBiaXMgMjAxNyB2ZXJ3ZW5kZXQsIDIwMTggd2lyZCBmw7xyIGRpZSBCZXVydGVpbHVuZyBkZXIgTW9kZWxscGVyZm9ybWFuY2UgenVyw7xja2dlaGFsdGVuLgoKYGBge3J9CgojIERpZSBiZXJlaXRzIGJlcmVjaG5ldGVuIEdydW5kZGF0ZW4gZGVzIERpYWdyYW1tcyB3ZXJkZW4gaGllciB3aWVkZXJ2ZXJ3ZW5kZXQuCiMgRGllIERhdGVud2VydGUgd2VyZGVuIGpldHp0IGFiZXIgYWxzIExpbmllbmRpYWdyYW1tIGVpbmdlZsO8Z3QuCnAgKyBnZW9tX2xpbmUoYWVzKHkgPSBJVlMsIGNvbG9yID0gKHllYXIoRGF0dW0pID09IDIwMTgpKSkKCmBgYAoKTW9kZWxsaWVydCBtYW4gZGllIG1vbmF0bGljaGVuIFNjaHdhbmt1bmdlbiwgZXJow7ZodCBzaWNoIGRlciBFcmtsw6RydW5nc2dlaGFsdCBkZXMgTW9kZWxscyBkZXV0bGljaC4gRGF6dSB3ZXJkZW4gZGllIE1vbmF0ZSBhbHMgendlaXN0ZWxsaWdlIFplaWNoZW5rZXR0ZW4gbW9kZWxsaWVydCAoIjAxIiBiaXMgIjEyIikuIGBSYCBlcnpldWd0IGRhcmF1cyBhdXRvbWF0aXNjaCAxMSBEdW1teXZhcmlhYmxlbiB6dXIgQWJiaWxkdW5nIGRlciBNb25hdGUgaW0gTW9kZWxsLiAKCmBgYHtyfQoKIyBEZXIgZWluZmFjaCBEYXRhZnJhbWUgaXZzX3NpbXBsZSBtaXQgZGVuIFNwYWx0ZW4gSVZTIHVuZCBEYXR1bQojIHdpciBoaWVyIGVyd2VpdGVydDogZGllIE51bW1lciBkZXMgTW9uYXRzIHdpcmQgYWxzIHp3ZWlzdGVsbGlnZSBaZWljaGVua2V0dGUgZXJnw6RuenQuCml2c19zaW1wbGUgPC0gaXZzX3NpbXBsZSAlPiUgCiAgbXV0YXRlKE1vbmF0ID0gc3RyX3BhZChtb250aChEYXR1bSksIDIsIHBhZCA9ICIwIikpCgojIEF1ZnRlaWxlbiBkZXIgRGF0ZW4gaW4gZWluIFRyYWluaW5ncy0gdW5kIGVpbiBUZXN0c2V0Cml2c19zaW1wbGVfdHJhaW4gPC0gaXZzX3NpbXBsZSAlPiUgZmlsdGVyKERhdHVtIDwgZGF0ZSgiMjAxOC0wMS0wMSIpKQppdnNfc2ltcGxlX3Rlc3QgPC0gaXZzX3NpbXBsZSAlPiUgZmlsdGVyKERhdHVtID49IGRhdGUoIjIwMTgtMDEtMDEiKSkKCiMgRXJuZXV0ZSBCZXJlY2hudW5nIGRlcyBNb2RlbGxzIC4uLgptb2QgPC0gbG0oZm9ybXVsYSA9IElWUyB+IERhdHVtICsgTW9uYXQsIGRhdGEgPSBpdnNfc2ltcGxlX3RyYWluKQoKIyAuLi4gdW5kIEF1c2dhYmUgZGVyIE1vZGVsbGVyZ2Vibmlzc2UKc3VtbWFyeShtb2QpCgpgYGAKCkRlciBBbnRlaWwgZGVyIGVya2zDpHJ0ZW4gVmFyaWFueiBlcmjDtmh0IHNpY2ggbnVuIGF1ZiDDvGJlciA4NiBQcm96ZW50LiBEaWUgbWVpc3RlbiBkZXIgU2Fpc2lvbi1EdW1taWVzIGhhYmVuIHN0YXRpc3Rpc2NoIHNpZ25pZmlrYW50ZSBLb2VmZml6aWVudGVuLCBnbGVpY2hlcyBnaWx0IGbDvHIgZGFzIE1vZGVsbCBpbSBHZXNhbXRlbiAodmdsLiBGLVN0YXRpc3RpaykuCgojIyMjIFByw7xmdW5nIGRlciBNb2RlbGxpZXJ1bmdzdm9yYXVzc2V0enVuZ2VuCldpciBwcsO8ZmVuIGRpZSBNb2RlbGxpZXJ1bmdzdm9yYXVzc2V0enVuZ2VuIGFuYWxvZyB6dSBbQmFja2hhdXMgZXQgYWwuICgyMDE4KV0oaHR0cHM6Ly93d3cuc3ByaW5nZXIuY29tL2RlL2Jvb2svOTc4MzY2MjU2NjU0MSksIFMuIDk4IGZmKS4KCigxKSBOaWNodGxpbmVhcml0w6R0OiBkaWUgZ3JhcGhpc2NoZSBEYXJzdGVsbHVuZyBsw6Rzc3QgLSB1bnRlciBCZXLDvGNrc2ljaHRpZ3VuZyBkZXIgU2Fpc29ua29tcG9uZW50ZSBlaW5lbiBkYXJ1bnRlciBsaWVnZW5kZW4gbGluZWFyZW4gVHJlbmQgdmVybXV0ZW4uCgooMikgRXJ3YXJ0dW5nc3dlcnQgZGVyIFN0w7ZyZ3LDtsOfZSA9IDA6IGlzdCBuaWNodCB2b24gQmVkZXV1dHVuZywgd2lya3Qgc2ljaCBnZ2YuIGF1ZiBkZW4gS29lZmZpemllbnRlbiBiMCBhdXMuCgooMykgRmFsc2NoZSBSZWdyZXNzb3JlbmF1c3dhaGw6IE11bHRpa29sbGluZWFyaXTDpHQgZmFsc2NoIHNwZXppZml6aWVydGVyIFJlZ3Jlc3NvcmVuIHZlcnplcnJ0IGRpZSBQYXJtZXRlcnNjaMOkdHplciwgYmVpIGZlaGxlbmRlciBNdWx0aWtvbGxpbmVhcml0w6R0IHdpcmtlbiBzaWUgc2ljaCB6dW1pbmRlc3Qgd2llZGVyIGF1ZiBkZW4gT3JkaW5hdGVuYWJzY2huaXR0IGIwIGF1cy4gTWl0ICREYXR1bSQgdW5kICRNb25hdCQgc2luZCBoaWVyIGFsbGVyZGluZ3Mga2VpbmUgw7xiZXJmbMO8c3NpZ2VuIFJlZ3Jlc3NvcmVuIGVya2VubmJhci4KCig0KSBIZXRlcm9za2VkYXN0aXppdMOkdDogRGVyIFBsb3QgZGVyIFJlc2lkdWVuIGdlZ2VuIGRpZSBlcmtsw6RydGUgVmFyaWFibGUgbMOkc3N0IGtlaW5lIGbDvHIgSGV0ZXJvc2tlZGFzdGl6aXTDpHQgdHlwaXNjaGVuIFZlcmzDpHVmZSBlcmtlbm5lbi4KCmBgYHtyfQoKIyBEYXRhZnJhbWUgdW0gUHJvZ25vc2V3ZXJ0ZSB1bmQgUmVzaWR1ZW4gZXJnw6RuemVuCmRmX21vZCA8LSBhdWdtZW50KG1vZCkKCiNTY2F0dGVycGxvdCBkZXIgUmVzaWR1ZW4gZ2VnZW4gZ2VzY2jDpHR6dGUgV2VydGUKZ2dwbG90KGRhdGEgPSBkZl9tb2QsIGFlcyh4ID0gLmZpdHRlZCwgeSA9IC5yZXNpZCkpICsKICBnZW9tX3BvaW50KCkKCmBgYAoKSGV0ZXJvc2tlZGFzdGl6aXTDpHQga2FubiBhdWNoIG1pdCBkZW0gR29sZGZlbGQtUXVhbmR0LVRlc3Qgw7xiZXJwcsO8ZnQgd2VyZGVuLiBEaWUgTnVsbGh5cG90aGVzZSAoSG9tb3NrZWRhc3Rpeml0w6R0KSBrYW5uIG5pY2h0IHZlcndvcmZlbiB3ZXJkZW4uCgpgYGB7cn0KIyBHb2xkZmVsZC1RdWFuZHQtVGVzdCBhdXMgZGVtIGxtdGVzdC1wYWNrYWdlLgpncXRlc3QobW9kKQoKYGBgCgoKKDUpIEF1dG9rb3JyZWxhdGlvbjogSW5iZXNvbmRlcmUgYmVpIFplaXRyZWloZW4gYmVzdGVodCBkaWUgR2VmYWhyIGRlciBWZXJ6ZXJydW5nIGRlcyBTdGFuZGFyZGZlaGxlcnMgZGVyIFJlZ3Jlc3Npb25za29lZmZpemllbnRlbiBkdXJjaCBhdXRva29ycmVsaWVydGUgUmVzaWR1ZW4uIEltIEVyZ2VibmlzIGVyZ2ViZW4gc2ljaCBkYW5uIHZlcnplcnJ0ZSBLb25maWRlbnppbnRlcnZhbGxlIGbDvHIgZGllIFJlZ3Jlc3Npb25za29lZmZpemllbnRlbi4gRWluZSBWaXN1ZWxsZSBQcsO8ZnVuZyBlcmZvbGd0IHdpZSBiZWkgZGVyIEhldGVyc2tlZGFzdGl6aXTDpHQgaW0gUGxvdCBkZXIgUmVzaWR1ZW4gZ2VnZW4gZGllIGdlc2Now6R0emVuIFdlcnRlLiBFYmVuc28gaXN0IGRpZSBQcsO8ZnVuZyBtaXQgRHVyYmluLVdhdHNvbi1UZXN0IG3DtmdsaWNoLCBkZXNzZW4gTnVsbGh5cG90aGVzZSAoa2VpbmUgQXV0b2tvcnJlbGF0aW9uKSBuaWNodCB2ZXJ3b3JmZW4gd2VyZGVuIGthbm4uCgpgYGB7cn0KIyBEdXJiaW4tV2F0c29uLVRlc3QgKHBhY2thZ2UgbG10ZXN0KQpkd3Rlc3QobW9kKQpgYGAKCig2KSBNdWx0aWtvbGxpbmVhcml0w6R0OiBTY2jDpHR6dW5nZW4gZsO8ciBSZWdyZXNzaW9uc2tvZWZmaXppZW50ZW4gd2VyZGVuIHVuenV2ZXJsw6Rzc2lnZXIsIHdlbm4gc2ljaCBkaWUgS29lZmZpemVudGVuIGF1cyBhbmRlcmVuIE1vZGVsbGtvZWZmaXppZW50ZW4gZXJyZWNobmVuIGxhc3Nlbi4gUGFhcndlaXNlIE11bHRpa29sbGluZWFyaXTDpHQgaXN0IHZvcmhhbmRlbiwgd2VubiBkZXIgQmV0cmFnIGRlciBwYWFyd2Vpc2VuIEtvcnJlbGF0aW9uZW4gbmFoZSAxIGlzdC4gQWJow6RuZ2lna2VpdGVuIHZvbiBtZWhyZXJlbiBhbmRlcmVuIFZhcmlhYmxlbiBrYW5uIGR1cmNoIGRpZSBUb2xlcmFueiBvZGVyIGRlcmVuIEtlaHJ3ZXJ0LCBkZW4gVmFyaWFuei1JbmZsYXRpb24tRmFjdG9yIChWSUYpIGVybWl0dGVsdCB3ZXJkZW4uIFZJRi1XZXJ0ZSBpbSBiZXJlaWNoIHZvbiAxMCBvZGVyIGdyw7bDn2VyIHNpbmQgYXVmIGplZGVuIEZhbGwgcHJvYmxlbWF0aXNjaC4gSW0gQmVpc3BpZWwgaXN0IGRpZSBNdWx0aWtvbGxpbmVhcml0w6R0IG1pdCBEYXR1bSBiencuIE1vbmF0IGFscyBSZWdyZXNzb3JlbiBuaWNodCByZWxldmFudC4KCmBgYHtyfQojIEFsbGUgU3BhbHRlbiBpbiBudW1lcmlzY2hlIFdlcnRlIHVtd2FuZGVsbgojIG0gPC0gaXZzX3NpbXBsZV90cmFpblssLTNdICU+JQojICAgbXV0YXRlKERhdHVtID0gYXMubnVtZXJpYyhEYXR1bSkpCgojIEtvcnJlbGF0aW9uc21hdHJpeCBiZXJlY2huZW4gdW5kIHZpc3VhbGlzaWVyZW4KIyBjb3JycGxvdChjb3JyID0gY29yKG0pLCBtZXRob2QgPSAicGllIikKCiMgVmFyaWFuei1JbmZsYXRpb24tRmFrdG9yZW4gYmVyZWNobmVuCiMgdmlmKG1vZCkKYGBgCgooNykgTm9ybWFsdmVydGVpbHVuZyBkZXIgUmVzaWR1ZW46IEJlaSBncm/Dn2VyIFN0aWNocHJvYmUgaXN0IGVpbmUgQWJ3ZWljaHVuZyB2b24gZGVyIE5vcm1hbHZlcnRlaWx1bmdzYW5uYWhtZSBuaWNodCBzbyB0cmFnaXNjaC4gRGUgUVEtUGxvdCBzaWVodCBhbGxlcmRpbmdzIG5pY2h0IHBlcmZla3QgYXVzLgoKYGBge3J9CnFxbm9ybShkZl9tb2QkLnJlc2lkKQpxcWxpbmUoZGZfbW9kJC5yZXNpZCwgZGF0YXggPSBGQUxTRSwgZGlzdHJpYnV0aW9uID0gcW5vcm0sCiAgICAgICBwcm9icyA9IGMoMC4yNSwgMC43NSksIHF0eXBlID0gNykKCmBgYAoKIyMjIEVyc3RlbGx1bmcgdm9uIFByb2dub3NlbgoKRGFzIGJlcmVjaG5ldGUgTW9kZWxsIGVybGF1YnQgZGllIEJlcmVjaG51bmcgdm9uIFByb2dub3Nld2VydGVuLiBEdXJjaCBkZW4gVmVyZ2xlaWNoIGRlciBQcm9nbm9zZXdlcnRlIGbDvHIgZGllIFRlc3RkYXRlbiBtaXQgZGVuIElzdC1XZXJ0ZW4gZGVyIFRlc3RkYXRlbiAoMjAxOCkga8O2bm5lbiBQZXJmb3JtYW5jZS1NYcOfZSBiZXJlY2huZXQgd2VyZGVuLCBkaWUgZGVuIFZlcmdsZWljaCB1bnRlcnNjaGllZGxpY2hlciBNb2RlbGxlIGVybGF1YmVuLgoKYGBge3J9CgojIFByb2dub3Nld2VydGUgYXVmZ3J1bmQgZGVzIGJlcmVjaG5ldGVuIE1vZGVsbHMgZXJnw6RuemVuCml2c19zaW1wbGVfdGVzdCA8LSBpdnNfc2ltcGxlX3Rlc3QgJT4lIGFkZF9wcmVkaWN0aW9ucyhtb2RlbCA9IG1vZCkKCiMgR3JhZmlzY2hlIERhcnN0ZWxsdW5nIGRlciBQcm9nbm9zZW4gKGdlc3RyaWNoZWx0KQpwICsgZ2VvbV9saW5lKGFlcyh5ID0gSVZTLCBjb2xvciA9ICh5ZWFyKERhdHVtKSA9PSAyMDE4KSkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBwcmVkKSwKICAgICAgICAgICAgbGluZXR5cGUgPSAyLCAjIGRhc2hlZAogICAgICAgICAgICBjb2xvciA9ICJyZWQiLAogICAgICAgICAgICBkYXRhID0gaXZzX3NpbXBsZV90ZXN0KQoKIyBQZXJmb3JtYW5jZS1NZXRyaWtlbgpmUGVyZm9ybWFuY2UgPC0gZnVuY3Rpb24oYWN0dWFsLCBwcmVkaWN0ZWQpIHsKICBsaXN0KG1hZSA9IE1ldHJpY3M6Om1hZShhY3R1YWwsIHByZWRpY3RlZCksCiAgICBtYXBlID0gTWV0cmljczo6bWFwZShhY3R1YWwsIHByZWRpY3RlZCksCiAgICBtc2UgPSBNZXRyaWNzOjptc2UoYWN0dWFsLCBwcmVkaWN0ZWQpLAogICAgcm1zZSA9IE1ldHJpY3M6OnJtc2UoYWN0dWFsLCBwcmVkaWN0ZWQpKSAlPiUgCiAgICBiaW5kX3Jvd3MoKQp9CgojIFBlcmZvcm1hbmNlLUJlcmVjaG51bmcgYXVmIGRlciBCYXNpcyBkZXIgVGVzdGRhdGVuCmZQZXJmb3JtYW5jZShpdnNfc2ltcGxlX3Rlc3QkSVZTLCBpdnNfc2ltcGxlX3Rlc3QkcHJlZCkKCmBgYAoKPCEtLSBBdXMgZGVuIFJlZ3Jlc3Npb25za29lZmZpemllbnRlbiBsw6Rzc3Qgc2ljaCBlaW5lIFNhaXNpb25maWd1ciBhYmxlaXRlbi4gRGllcyBnaWx0IMOkaG5saWNoLCB3ZW5uIG1hbiBCb3gtUGxvdHMgZGVyIG1vbmF0bGljaCBncnVwcGllcnRlbiBEYXRlbiBlcnN0ZWxsdC4gLS0+Cgo8IS0tIGBgYHtyfSAtLT4KCjwhLS0gaXZzX3NpbXBsZV90cmFpbiA8LSBpdnNfc2ltcGxlX3RyYWluICU+JSBhZGRfcHJlZGljdGlvbnMobW9kZWwgPSBtb2QpIC0tPgoKPCEtLSBnZ3Bsb3QoaXZzX3NpbXBsZV90cmFpbiwgYWVzKHggPSBNb25hdCkpICsgLS0+CjwhLS0gICAjIGdlb21fYm94cGxvdChhZXMoeSA9IElWUyAtIG1lYW4oSVZTKSksIGFscGhhID0gMC4yLCBjb2xvciA9ICJncmV5IikgKyAtLT4KPCEtLSAgIGdlb21fYm94cGxvdChhZXMoeSA9IElWUyAtIG1lYW4oSVZTKSksIGFscGhhID0gMC4yLCBjb2xvciA9ICJncmV5IikgKyAtLT4KPCEtLSAgICMgZ2VvbV9wb2ludChhZXMoeSA9IElWUyAtIG1lYW4oSVZTKSksIGFscGhhID0gMC41KSArIC0tPgo8IS0tICAgIyBnZW9tX3BvaW50KGFlcyh5ID0gcHJlZCAtIG1lYW4oSVZTKSksIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArIC0tPgo8IS0tICAgbGFicyh0aXRsZSA9ICJtb25hdGxpY2hlIEludmVya2VocnNzZXR6dW5nZW4gdm9uIFBlcnNvbmVua3JhZnR3YWdlbiIsIC0tPgo8IS0tICAgICAgICBzdWJ0aXRsZSA9ICJTY2h3ZWl6LCAyMDEzIC0gMjAxOCIpIC0tPgoKCjwhLS0gYGBgIC0tPgoKIyMjIFRlc3QgZWluZXIgYWx0ZXJuYXRpdmUgTW9kZWxsaWVydW5nIGFscyBBUklNQQoKYGBge3J9CgppdnNfdHMgPC0gdHMoaXZzX3NpbXBsZV90cmFpbiRJVlMsIHN0YXJ0ID0gYygyMDEzLDEpLCBmcmVxdWVuY3kgPSAxMikKCml2c190cyAlPiUgZ2d0c2Rpc3BsYXkobGFnLm1heCA9IDYwKQppdnNfdHMgJT4lIAogIGRpZmYoKSAlPiUgCiAgZGlmZihsYWcgPSAxMikgJT4lIAogIGdndHNkaXNwbGF5KGxhZy5tYXggPSA2MCwgbWFpbiA9ICJpdnNfc2ltcGxlX3RyYWluJElWUywgdHdvIHRpbWVzIGRpZmZlcmVudGlhdGVkIikKCm1vZCA8LSBzYXJpbWEoaXZzX3RzLCAxLDEsMCwgMCwxLDEsIDEyKQpzYXJpbWEoaXZzX3RzLCAyLDEsMCwgMCwxLDEsIDEyKQoKaXZzX3RzICU+JSBwbG90KCkKaXZzX3RzX2FsbCA8LSB0cyhpdnNfc2ltcGxlJElWUywgc3RhcnQgPSBjKDIwMTMsMSksIGZyZXF1ZW5jeSA9IDEyKQppdnNfdHNfYWxsICU+JSBwbG90KCkKCnByZWRpY3Rpb25zIDwtIHNhcmltYS5mb3IoaXZzX3RzLCAyLDEsMCwgMCwxLDEsIDEyLCBuLmFoZWFkID0gMTIpCiMgbGluZXMoaXZzX3RzX2FsbCkKCmZQZXJmb3JtYW5jZShpdnNfc2ltcGxlX3Rlc3QkSVZTLCBwcmVkaWN0aW9ucyRwcmVkKQpgYGAKCgojIyMgUmVkdWt0aW9uIGRlciBQcsOkZGlrdG9yZW4gLyBWMSBTYWlzb25hbGUgVm9yaGVyc2FnZW4KIyMjIFJlZHVrdGlvbiBkZXIgUHLDpGRpa3RvcmVuIC8gVjIgbW9uYXRsaWNoZSBWb3JoZXJzYWdlbiBtaXQgVGltZSBMYWcKCiMjIyBEaWZmZXJlbnppZXJ1bmcgZGVyIEFudHJpZWJzYXJ0CgpEaWUgV2llZGVyaG9sdW5nIGRlciBBbmFseXNlIG1pdCBkZW0genVzw6R0emxpY2hlbiBSZWdyZXNzb3IgemVpZ3QgZWluIHbDtmxsaWcgYW5kZXJlcyBCaWxkLgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KCiMgRGF0ZW4gZGVzIFN0YXRpc3Rpc2NoZW4gQnVuZGVzYW10ZXMgbWl0IEluZm9ybWF0aW9uZW4genVyIFRyZWlic3RvZmZhcnQKaXZzX3Jhd19mdWVsIDwtCiAgcmVhZF9jc3YoZmlsZSA9ICJEYXRlbi8yMDE5MDgyNCBOZXV6dWxhc3N1bmdlbiBDSCBUcmVpYnN0b2ZmLmNzdiIsCiAgICAgICAgICAgc2tpcCA9IDIsCiAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlKGVuY29kaW5nID0gImxhdGluMSIpKSAjIFdpbmRvd3MgTGF0aW4gMQoKIyBEYXRlbiB2b3JiZXJlaXRlbgppdnNfZnVlbCA8LSBpdnNfcmF3X2Z1ZWwgJT4lCiAgc2VsZWN0KC0iRmFocnpldWdncnVwcGUgLyAtYXJ0IikgJT4lICMgRXMgd3VyZGUgbnVyIFBlcnNvbmVua3JhZnR3YWdlbiBhdXNnZXfDpGhsdCwgU3BhbHRlIEZhaHJ6ZXVncnVwcGUgbMO2c2NoZW4KICBnYXRoZXIoa2V5ID0gSmFociwgdmFsdWUgPSAiSVZTIiwgLU1vbmF0LCAtVHJlaWJzdG9mZikgJT4lICMgZGllIEphaHJlc3NwYWx0ZW4gaW4gWmVpbGVuIHVtYmF1ZW4KICBtdXRhdGUoRGF0dW0gPSBtb250aHNFbmQoSmFociwgTW9uYXQpKSAlPiUgICMgSmFociBNb25hdCB1bWJhdWVuIGF1ZiBlaW5lIERhdHVtIHp1bSBNb25hdHNlbmRlCiAgbXV0YXRlKE1vbmF0ID0gc3RyX3BhZChtb250aChEYXR1bSksIDIsIHBhZCA9ICIwIikpICU+JSAKICBmaWx0ZXIoRGF0dW0gPiB5bWQoIjIwMTItMTItMzEiKSkgJT4lIAogIHNlbGVjdChEYXR1bSwgTW9uYXQsIFRyZWlic3RvZmYsIElWUykKCiMgR3JhcGhpc2NoZSBEYXJzdGVsbHVuZywgZGlmZmVyZW56aWVydCBuYWNoIFRyZWlic3RvZmZhcnQsIGVyemV1Z2VuIGFiZXIgbm9jaCBuaWNodCBhbnplaWdlbgpwIDwtIGl2c19mdWVsICU+JQogIGdncGxvdChhZXMoeCA9IERhdHVtLCBjb2xvciA9IFRyZWlic3RvZmYsLCBsaW5ldHlwZSA9IFRyZWlic3RvZmYpKSArCiAgbGFicyh0aXRsZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIFBLVywgbmFjaCBUcmVpYnN0b2ZmYXJ0IiwKICAgICAgIHN1YnRpdGxlID0gIlNjaHdlaXosIDIwMTMgLSAyMDE4IikgICsKICBzY2FsZV94X2RhdGUoCiAgICBuYW1lID0gIiIsCiAgICBsaW1pdHMgPSBjKHltZCgiMjAxMy0wMS0wMSIsICIyMDE4LTEyLTMxIikpLAogICAgZGF0ZV9sYWJlbHMgPSAiJW0vJXkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKQoKIyBMaW5lYXJlIFNrYWxhCnAgKyBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIHBybyBNb25hdCIsIGxhYmVscyA9IGZvcm1hdFQpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBJVlMpKQoKIyBMb2dhcml0aG1pc2NoZSBTa2FsYQpwICsgc2NhbGVfeV9sb2cxMChuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUyksIAogICAgICAgICAgICBkYXRhID0gaXZzX2Z1ZWxbaXZzX2Z1ZWwkSVZTID4gMCxdKQoKYGBgCkRpZSBUcmVpYnN0b2ZmYXJ0ZW4gIkFuZGVyZXIiIHVuZCAiT2huZSBNb3RvciIgc3BpZWxlbiBpbiBkZXIgQW5hbHlzZSBrZWluZSBiZXNvbmRlcmUgUm9sbGUuIFp1ciBiZXNzZXJlbiDDnGJlcnNpY2h0bGljaGtlaXQgd2VyZGVuIHNpZSBhdXNnZXNjaGxvc3Nlbi4KCmBgYHtyfQoKIyBBdXNzY2hsdXNzIHZvbiBHYXMgdW5kIFRyZWlic3RvZmZhcnRlbiAiQW5kZXJlciIgc293aWUgb2huZSBNb3RvcgppdnNfZnVlbCA8LSBpdnNfZnVlbCAlPiUgCiAgIyBmaWx0ZXIoIVRyZWlic3RvZmYgJWluJSBjKCJBbmRlcmVyIiwgIkdhcyAobW9uby0gdW5kIGJpdmFsZW50KSIsICJPaG5lIE1vdG9yIikpCiAgZmlsdGVyKCFUcmVpYnN0b2ZmICVpbiUgYygiQW5kZXJlciIsICJPaG5lIE1vdG9yIikpCgojIExpbmVhcmUgU2thbGEKcCArIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUywgbGluZXR5cGUgPSBUcmVpYnN0b2ZmKSwgZGF0YSA9IGl2c19mdWVsKQoKIyBMb2dhcml0aG1pc2NoZSBTa2FsYQpwICsgc2NhbGVfeV9sb2cxMChuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUywgbGluZXR5cGUgPSBUcmVpYnN0b2ZmKSwgCiAgICAgICAgICAgIGRhdGEgPSBpdnNfZnVlbFtpdnNfZnVlbCRJVlMgPiAwLF0pCgpgYGAKCiMjIyBNb2RlbGxlIGplIFRyZWlic3RvZmZhcnQKCiMjIyMgTW9kZWxsZSBiZXJlY2huZW4gdW5kIHBsb3R0ZW4KCmBgYHtyfQojIERhdGVuIGluIFRyYWluaW5nIHVuZCBUZXN0IGF1ZnNwbGl0dGVuCml2c190cmFpbiA8LSBpdnNfZnVlbCAlPiUgZmlsdGVyKERhdHVtIDwgZGF0ZSgiMjAxOC0wMS0wMSIpKQppdnNfdGVzdCA8LSBpdnNfZnVlbCAlPiUgZmlsdGVyKERhdHVtID49IGRhdGUoIjIwMTgtMDEtMDEiKSkKCiMgZGFzIGxpbmVhcmUgTW9kZWxsIGluIGVpbmVyIEZ1bmt0aW9uIGthcHNlbG4KZk1vZCA8LSBmdW5jdGlvbihkZil7CiAgbG0oSVZTIH4gRGF0dW0gKyBNb25hdCwgZGF0YSA9IGRmKQp9CgojIGplIFRyZWlic3RvZmZhcnQgZGllIFRyYWluaW5nc2RhdGVuIGdydXBwaWVyZW4gdW5kIGluIGVpbmVuIFVudGVyZGF0YWZyYW1lIHNhbW1tZWxuCml2c19tb2RlbHMgPC0gaXZzX3RyYWluICU+JSAKICBncm91cF9ieShUcmVpYnN0b2ZmKSAlPiUKICBuZXN0KGRhdGEgPSBjKERhdHVtLCBNb25hdCwgSVZTKSkgJT4lICMgZWluIERhdGVuc2F0eiBqZSBUcmVpYnN0b2ZmYXJ0IG1pdCBVbnRlcmRhdGFmcmFtZQogIG11dGF0ZSggIyBmw7xyIGplZGUgVHJlaWJzdG9mZmFydCAuLi4KICAgIG1vZGVsID0gbWFwKGRhdGEsIGZNb2QpLCAjIC4uLiBiZXJlY2huZSBlaW4gbGluZWFyZXMgTW9kZWxsCiAgICBkYXRhID0gbWFwMihkYXRhLCBtb2RlbCwgYWRkX3Jlc2lkdWFscyksICMgLi4uIFJlc2lkdWVuIGhpbnp1ZsO8Z2VuCiAgICBkYXRhID0gbWFwMihkYXRhLCBtb2RlbCwgYWRkX3ByZWRpY3Rpb25zKSwgIyAuLi4gdW5kIGdlc2Now6R0enRlIFdlcnRlCiAgICBnbGFuY2UgPSBtYXAobW9kZWwsIGJyb29tOjpnbGFuY2UpICMgS2Vubnp1YWhsZW4genUgTW9kZWxscGVyZm9ybWFuY2UgYmVyZWNobmVuCiApCgojIERpZSBVbnRlcmRhdGFmcmFtZXMgd2llZGVyIGF1ZmzDtnNlbiAuLi4KaXZzX3RyYWluIDwtIGl2c19tb2RlbHMgJT4lIHVubmVzdChjb2xzID0gYyhkYXRhKSkgJT4lCiAgc2VsZWN0KC1tb2RlbCwgLWdsYW5jZSkKCiMgLi4uIHVuZCBNb2RlbGxtZXRyaWtlbiBpbiBlaW5lbSBlaWdlbmVuIGRmIHNwZWljaGVybi4KaXZzX21vZGVscyA8LSBpdnNfbW9kZWxzICU+JSAKICBzZWxlY3QoLWRhdGEpICU+JSAKICB1bm5lc3QoY29scyA9IGMoZ2xhbmNlKSkKCiMgUGxvdHMKaXZzX3RyYWluW2l2c190cmFpbiRJVlMgPiAwICYgaXZzX3RyYWluJHByZWQgPiAwLF0gJT4lIAogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKyAjIERhdHVtIGF1ZiBkZXIgeC1BY2hzZWwKICBnZW9tX2xpbmUoYWVzKHkgPSBJVlMpLCBjb2xvciA9ICJyZWQiKSArICMgdGF0c8OkY2hsaWNoZSBXZXJ0ZSB1bmQgLi4uLgogIGdlb21fbGluZShhZXMoeSA9IHByZWQpLCBjb2xvciA9ICJncmV5IikgKyAjIFByZWRpa3RvcmVuIGF1ZiBkZXIgeS1BY2hzZQogIHNjYWxlX3lfbG9nMTAoKSArICMgTG9nYXJpdGhtaXNjaGUgT3JkaW5hdGUKICBmYWNldF93cmFwKCB+IFRyZWlic3RvZmYpICMga2xlaW5lIFN1YmRpYWdyYW1tIGplIFRyZWlic3RvZmZhcnQuCgojIE1vZGVsbG1ldHJpa2VuIGF1c2dlYmVuCml2c19tb2RlbHMgJT4lIGFycmFuZ2Uoci5zcXVhcmVkKSAKCmBgYAoKIyMjIyBQZXJmb3JtYW5jZWJlcmVjaG51bmcKCkplIFRyZWlic3RvZmZhcnQgd2VyZGVuIGbDvHIgZGFzIGpld2VpbGdlIE1vZGVsbCBkaWUgTW9kZWxsa2VubnphaGxlbiBlcm1pdHRlbHQuCgpgYGB7cn0KIyBNb2RlbGxwZXJmb3JtYW5jZSBiZXJlY2huZW4KCml2c190ZXN0IDwtIGl2c190ZXN0ICU+JQogIGdyb3VwX2J5KFRyZWlic3RvZmYpICU+JSAKICBuZXN0KGRhdGEgPSBjKERhdHVtLCBNb25hdCwgSVZTKSkgJT4lICMgIm5lc3QiIGplIFRyZWlic3RvZmZhcnQKICBhZGRfY29sdW1uKG1vZGVsID0gaXZzX21vZGVscyRtb2RlbCkgJT4lICMgYmVyZWl0cyBiZXJlY2huZXRlcyBNb2RlbGwgaGluenVmw7xnZW4KICBtdXRhdGUoCiAgICBkYXRhID0gbWFwMihkYXRhLCBtb2RlbCwgYWRkX3Jlc2lkdWFscyksICMgUmVzaWR1ZW4gZXJnw6RuemVuIC4uLgogICAgZGF0YSA9IG1hcDIoZGF0YSwgbW9kZWwsIGFkZF9wcmVkaWN0aW9ucyksICMgVm9yaGVyc2FnZXdlcnRlIGRhenVnZWJlbgogICAgcGZtYyA9IG1hcDIobW9kZWwsIGRhdGEsIGZQZXJmb3JtYW5jZSkpICU+JSAjIE1vZGVsbGtlbm56YWhsIGJlcmVjaG5lbi4KICBzZWxlY3QoLW1vZGVsKSAjIGRpZSBTcGFsdGUgbW9kZWwgd2lyZCBuaWNodCBtZWhyIGJlbsO2dGlndAoKaWZzX3Rlc3RfbW9kZWxzIDwtIGl2c190ZXN0ICU+JSAjIGNyZWF0ZSBkYXRhZnJhbWUgd2l0aCBtb2RlbCBtZXRyaWNzCiAgc2VsZWN0KC1kYXRhKSAlPiUgCiAgdW5uZXN0KHBmbWMpCgppdnNfdGVzdCA8LSBpdnNfdGVzdCAlPiUgIyBlcnN0ZWxsZSBlaW5lbiBEYXRhZnJhbWUgbWl0IFByb2dub3NlbiB1bmQgUmVzaWR1ZW4KICBzZWxlY3QoLXBmbWMpICU+JSAKICB1bm5lc3QoZGF0YSkKCml2c190ZXN0W2l2c190ZXN0JElWUyA+IDAgJiBpdnNfdGVzdCRwcmVkID4gMCxdICU+JSAjIGJpdHRlIGtlaW5lIE51bGxlbiwgZGllIGxvZ2FyaXRobWllcnQgd2VyZGVuIC4uLgogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUyksIGNvbG9yID0gInJlZCIpICsgIyB0YXRzw6RjaGxpY2hlIFdlcnRlCiAgZ2VvbV9saW5lKGFlcyh5ID0gcHJlZCksIGNvbG9yID0gImdyZXkiKSArICMgVm9yaGVyc2FnZXdlcnRlCiAgc2NhbGVfeV9sb2cxMCgpICsgIyBsb2dhcml0aG1pc2NoZSBTa2FsYQogIGZhY2V0X3dyYXAofiBUcmVpYnN0b2ZmKSAjIFVudGVyZGlhZ3JhbW0gamUgVHJlaWJzdG9mZmFydAoKYGBgCgojIyMgUXVlbGxlbgoKQmFja2hhdXMgZXQgYWwuICgyMDE4KTogTXVsdGl2YXJpYXRlIEFuYWx5c2VtZXRob2Rlbi4gRWluZSBhbndlbmR1bmdzb3JpZW50aWVydGUgRWluZsO8aHJ1bmcuIDE1IEF1ZmwuIEJlcmxpbi4gSGVpZGVsYmVyZy4gW1NwcmluZ2VyLVZlcmxhZ10oaHR0cHM6Ly93d3cuc3ByaW5nZXIuY29tL2RlL2Jvb2svOTc4MzY2MjU2NjU0MSkuCgpJbGcsIE1hcmt1czsgQmF1bWVpc3RlciwgQWxleGFuZGVyICgyMDE5KTogQW5hbHl0aWNzIGltIE1hcmtldGluZy1Db250cm9sbGluZy4gSW46IERpZSBEaWdpdGFsaXNpZXJ1bmcgZGVzIENvbnRyb2xsaW5nczogQW53ZW5kdW5nc2JlaXNwaWVsZSBhdXMgVGhlb3JpZSB1bmQgUHJheGlzLCBocnNnLiB2b24gSW1rZSBLZWltZXIgdW5kIFVscmljaCBFZ2xlLiBTcHJpbmdlci4KClJ1cHBlcnQsIERhdmlkOyBNYXR0ZXNvbiwgRGF2aWQgUy4gKDIwMTUpOiBTdGF0aXN0aWNzIGFuZCBEYXRhIEFuYWx5c2lzIGZvciBGaW5hbmNpYWwgRW5naW5lZXJpbmcgW1NwcmluZ2VyLVZlcmxhZ10oaHR0cHM6Ly93d3cuc3ByaW5nZXIuY29tL2RlL2Jvb2svOTc4MTQ5MzkyNjEzOCk=